<?php

namespace App\Admin\Controllers;

use App\Admin\Repositories\NaturalSpelling;
use App\Models\NaturalSpelling as Model;
use App\Models\TeachingMaterial;
use Dcat\Admin\Admin;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Http\JsonResponse;
use Dcat\Admin\Models\Administrator;
use Dcat\Admin\Show;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Traits\HasUploadedFile;
use Illuminate\Support\Facades\Validator;

class NaturalSpellingController extends AdminController
{
    use HasUploadedFile;
    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        Admin::style(
            <<<CSS
        table {
            text-align: center;
        }
CSS
        );
        $user = Admin::user();
        if ($user->is_admin == -1) {
            $class = $user->spelling()->getQuery();
            $two = new NaturalSpelling($class);
        } else {
            $two = new NaturalSpelling();
        }
        return Grid::make($two, function (Grid $grid) use ($user) {
            if ($user->is_admin == 1) {
                $grid->model()->with('mechanism');
            }
            $grid->column('id')->sortable();
            if ($user->is_admin == 1) {
                $grid->column('mechanism.name', '所属机构');
            }
            $grid->column('name');
            $grid->column('data', '自然拼读相关单词')->display(function ($value) {
                if (!empty($value)) {
                    return array_column($value, 'name');
                }
                return '无';
            })->label();
            $grid->column('created_at');
            $grid->column('updated_at')->sortable();

            $grid->filter(function (Grid\Filter $filter) {
                $filter->panel();
                $filter->equal('book_id', '所属教材')
                    ->select(TeachingMaterial::where('mechanism_id', Admin::user()->id)
                        ->pluck('name', 'id')->toArray())
                    ->width(3)->load('unit_id', 'books/select');
                $filter->equal('unit_id', '所属单元')->select()->width(3);
            });
        });
    }

    /**
     * Make a show builder.
     *
     * @param mixed $id
     *
     * @return Show
     */
    protected function detail($id)
    {
        return Show::make($id, new NaturalSpelling(), function (Show $show) {
            $show->field('id');
            $show->field('mechanism_id');
            $show->field('name');
            $show->field('data');
            $show->field('created_at');
            $show->field('updated_at');
        });
    }

    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        $user = Admin::user();
        return Form::make(new NaturalSpelling(), function (Form $form) use ($user) {
            $form->display('id');
            if ($user->is_admin == 1) {
                $form->select('mechanism_id', '所属机构')
                    ->options(Administrator::where('is_admin', -1)
                        ->pluck('name', 'id')->toArray())->required();
            }
            $form->text('name')->required()->maxLength(30);
            if (Admin::user()->is_admin == -1) {
                $form->hidden('mechanism_id')->default(Admin::user()->id);
            }
            $form->tableCustom('data', '自然拼读');
        
            $form->display('created_at');
            $form->display('updated_at');
        });
    }

    public function store()
    {
        $request = request()->toArray();
        $validate = Validator::make($request, [
            'name' => 'required|string',
            'data' => 'required|array',
            'data.*.name' => 'required|string',
            'data.*.word' => 'required|string',
            'data.*.pic' => 'required|file',
            'data.*.mp3' => 'required|file',
            'data.*.syllable.*.text' => 'required|string',
            'data.*.syllable.*.pronunciation' => 'required|file',
        ], [
            'name.required' => '自然拼读名称必须填写',
            'data.required' => '自然拼读必须填写',
            'data.array' => '自然拼读必须是个数组',
            'data.*.name.required' => '自然拼读中的单词必须填写',
            'data.*.word.required' => '自然拼读中的文案必须填写',
            'data.*.pic.required' => '自然拼读中的图片必须填写',
            'data.*.mp3.required' => '自然拼读中的音频必须填写',
            'data.*.syllable.*.text.required' => '音节中的文本必须填写',
            'data.*.syllable.*.pronunciation.required' => '音节中的发音必须上传',
        ]);
        if ($validate->fails()) {
            return $this->errorValidatorResponse($validate);
        }
        foreach ($request['data'] as $key => $data) {
            $request['data'][$key]['pic'] = $this->handle($data['pic']);
            $request['data'][$key]['mp3'] = $this->handle($data['mp3']);
            foreach ($data['syllable'] as $k => $da) {
                $request['data'][$key]['syllable'][$k]['pronunciation'] = $this->handle($da['pronunciation']);
            }
        }
        $jsonResponse = new JsonResponse();
        try {
            Model::create($request);
        } catch (\Exception $exception) {
            $jsonResponse->error($exception->getMessage());
            return $jsonResponse->send();
        }
        $jsonResponse->redirect(admin_url('spelling'))
            ->success(trans('admin.save_succeeded'));

        return $jsonResponse->send();
    }

    public function update($id)
    {
        $request = request()->toArray();
        $validate = Validator::make($request, [
            'name' => 'required|string',
            'data' => 'required|array',
            'data.*.name' => 'required|string',
            'data.*.word' => 'required|string',
            'data.*.syllable.*.text' => 'required|string',
        ], [
            'name.required' => '自然拼读名称必须填写',
            'data.required' => '自然拼读必须填写',
            'data.array' => '自然拼读必须是个数组',
            'data.*.name.required' => '自然拼读中的单词必须填写',
            'data.*.word.required' => '自然拼读中的文案必须填写',
            'data.*.syllable.*.text.required' => '音节中的文本必须填写',
        ]);
        if ($validate->fails()) {
            return $this->errorValidatorResponse($validate);
        }
        foreach ($request['data'] as $key => $data) {
            if (!is_string($data['mp3'])) {
                $request['data'][$key]['mp3'] = $this->handle($data['mp3']);
            }
            if (!is_string($data['pic'])) {
                $request['data'][$key]['pic'] = $this->handle($data['pic']);
            }
            foreach ($data['syllable'] as $k => $da) {
                if (!is_string($da['pronunciation'])) {
                    $request['data'][$key]['syllable'][$k]['pronunciation'] = $this->handle($da['pronunciation']);
                }
            }
        }
        $tests = Model::findOrfail($id);
        $jsonResponse = new JsonResponse();
        try {
            $tests->update($request);
        } catch (\Exception $exception) {
            $jsonResponse->error($exception->getMessage());
            return $jsonResponse->send();
        }
        $jsonResponse->redirect(admin_url('spelling'))
            ->success(trans('admin.save_succeeded'));
        return $jsonResponse->send();
    }

    protected function errorValidatorResponse($validator)
    {
        $messages = $validator->errors()->toArray();
        $errMsg   = [];

        if ($messages) {
            foreach ($messages as $field => $errors) {
                foreach ($errors as $error) {
                    $errMsg[] = $error;
                }
            }
        }

        if (!empty($errMsg)) {
            $errMsg = implode(",", $errMsg);
        }
        $jsonResponse = new JsonResponse();
        $jsonResponse->error($errMsg);

        return $jsonResponse->send();
    }

    public function handle($file)
    {
        $disk = $this->disk('admin');

        $newName = md5($file->getClientOriginalName().time());
        $basedDir = 'natural_spelling/files';
        $newName = substr($newName, 5, 8).'-'.rand(1111, 99999).'.'.$file->getClientOriginalExtension();

        $disk->putFileAs($basedDir, $file, $newName);

        return "{$basedDir}/$newName";
    }
}
